/**
 * 当前会话访问的卖酒服务器相关类
 * 
 * + 卖酒服务器类
 * + 关联的商户
 * + 关联的业务员电子名片信息
 */
import store from '../../store/index'
import { JxbHttpClient } from './session';
import SellingServerUtil, { SellingServer } from '../sellingServer';
import SellingServerAdapter from "../../dataAdapter/sellingServerAdapter"
import { JxbResponse } from '../../utils/network';
import SessionUserUtil from './sessionUser';

/**
 * 当前会话访问的卖酒服务器
 */
export class SessionSellingServer extends SellingServer
{
    /**
     * @returns {boolean} 客户是否已确认找他买酒 true = 已确认找他买酒， false = 临时访问
     */
    get isConfirmed(){
        return !!this._data.isConfirmed
    }

    /**
     * @returns {string} 购物车为空时的占位图地址
     */
    get emptyShopCartBgUri(){
        return this._data.customeTemplate.emptyShopCartBgUri
    }

    /**
     * 获取上一次访问的卖酒服务器
     * 
     * @returns {SessionSellingServer} 上次访问的卖酒服务器信息
     */
    getTheLastAccessedServer(){
        return new Promise(resolve => {
            resolve(new SessionSellingServer(this._data.lastServerData))
        })
    }
}

/**
 * 会话访问的卖酒服务器工具类
 */
export default class SessionSellingServerUtil
{
    
    /**
     * 从服务器端请求用户信息
     * 
     * @returns {Promise<object>}
     */
    static requestServer() {
        return (new JxbHttpClient()).request('AppMaster/AppletSession/getSellingServerInfo')
        .then(jxbResps => {
            let activeServerData = jxbResps.data.liquorSellingServer,
                lastServerData = jxbResps.data.lastAccessedServer,
                recommendServerData = jxbResps.data.recommendedServer;
            let sellingServerData = SellingServerAdapter.convert(activeServerData)
            if(typeof lastServerData === 'object'){
                sellingServerData.lastServerData = SellingServerAdapter.convert(lastServerData)
            }
            if(typeof recommendServerData === 'object'){
                sellingServerData.recommendServerData = SellingServerAdapter.convert(recommendServerData)
            }
            return sellingServerData
        })
    }

    /**
     * 从服务器直接获取当前会话用户信息
     * 
     * @returns {Promise<SessionSellingServer>}
     */
    static getInstanceFromServer(){
        return this.requestServer()
        .then(data => {
            return new SessionSellingServer(data)
        })
    }

    /**
     * 获取会话用户实例
     * 
     * 默认从缓存中获取实例，如果失败则从服务器获取
     * @returns {Promise<SessionSellingServer>}
     */
    static getInstance(){
        let  prom, sellingServer = store.global('SessionSellingServer')
        if(sellingServer instanceof SessionSellingServer && Object.keys(sellingServer._data).length > 0){
            prom = new Promise(resolve => {
                resolve(sellingServer)
            })
        }else{
            let cacheData = this.requestCacheSync()
            if(Object.keys(cacheData).length === 0){
                // 刷新缓存并获取 SessionSellingServer 实例
                prom = this.renewCache()
            }else{
                sellingServer = new SessionSellingServer(cacheData)
                store.global('SessionSellingServer', sellingServer)
                prom = new Promise((resolve)=>{
                    resolve(sellingServer)
                })
            }
        }
        
        return prom
    }
    /**
     * 获取实例（同步）
     * 
     * 
     * 立即返回当前访问的卖酒服务器实例
     * 
     * **Bug&Tips**
     * 
     * + 由于该方法只从内存和本地缓存中获取相关信息，不会向服务器发起请求
     * + 使用该方法时，请确保全局变量中或本地缓存中已经存在相关数据，或者在获取后对结果进行判断
     * + 当本地没有缓存信息时调用了本方法将会返回null
     * @returns {SessionSellingServer}
     */
    static getInstanceSync(){
        let sellingServer = store.global('SessionSellingServer')
        if(sellingServer instanceof SessionSellingServer && Object.keys(sellingServer._data).length > 0){
            // do nothing
        }else{
            // 内存中没有缓存，从本地数据库中获取
            let cacheData = this.requestCacheSync()
            if(Object.keys(cacheData).length > 0){
                sellingServer = new SessionSellingServer(cacheData)
                store.global('SessionSellingServer', sellingServer)
            }else{
                sellingServer = null
            }
        }
        return sellingServer
    }
    /**
     * 获取缓存数据
     * 
     * @returns {object}
     */
    static requestCacheSync(){
        let cacheData = wx.getStorageSync('SessionSellingServer')
        if(typeof cacheData !== 'object'){
            cacheData = {}
        }
        return cacheData
    }
    /**
     * 更新本地缓存
     * 
     * newInstance为`SessionSellingServer`的实例时直接将该值更新到缓存中，否则从服务器同步信息到本地缓存
     * 
     * @param {SessionSellingServer} newInstance 新的实例
     * @returns {Promise<SessionSellingServer>} 返回最新的缓存数据
     */
    static renewCache(newInstance = undefined) {
        let instanceDataProm,renewFromServer = false
        let promCacheName = 'sellingServer.renewCacheProm'
        if(newInstance instanceof SessionSellingServer){
            instanceDataProm = Promise.resolve(newInstance)
        }else{
            renewFromServer = true
            instanceDataProm = store.global(promCacheName)
            if(instanceDataProm instanceof Promise){
                // do nothing 复用已存在的Promise实例
                console.debug('并发检测，存在并发的刷新sellingServer的请求，复用已向全局声明的请求', instanceDataProm)
            }else {
                console.debug('并发检测，不存在并发的刷新sellingServer的请求')
                instanceDataProm =  this.getInstanceFromServer()
            }
        }
        let prom =instanceDataProm.then(instance => {
            renewFromServer && console.debug('从远程获取到sellingServer数据，更新本地缓存并存到全局数据中')
            store.global('SessionSellingServer', instance)
            wx.setStorageSync('SessionSellingServer', instance._data)
            // 兼容原缓存方式
            // todo index/index接口的缓存 agent 需要在这里处理
            // 缓存 getInstance
            wx.setStorageSync("agent", {
                agent_name: instance._data.agentData.name
            });
            wx.setStorageSync("shop_name", instance._data.showName);
            wx.setStorageSync("store", instance._data.showName);
            wx.setStorageSync("consultantId", instance._data.vCardId);
            renewFromServer && store.global(promCacheName, null) // 向全局声明请求已结束
            return instance
        }).catch(error => {
            renewFromServer && store.global(promCacheName, null) // 向全局声明请求已结束
            throw error
        })
        renewFromServer && store.global(promCacheName, instanceDataProm) // 向全局声明请求已存在
        return prom
    }

    /**
     * 切换卖酒服务器
     * 
     * @param {SellingServer|number} toServer 
     * @returns {Promise<string>}
     */
    static switchSellingServer(toServer){
        return (new JxbHttpClient()).request({
            url: 'AppMaster/AppletSession/chooseNewServer',
            data: {
                salesmanId: (toServer instanceof SellingServer)?toServer.salesmanId : toServer
            },
            method: 'POST'
        }).then(jxbResp => {
            return jxbResp.message
        })
    }

    /**
     * 切换销售模式
     * 
     * @param {number} type 1=零售，2=批发 
     * @returns {Promise<JxbResponse>}
     */
    static switchSalesModel(type){
        return JxbHttpClient.getClient().post({
            url: '/AppMaster/SellingServer/selectSaleType',
            data: {
                sale_type: type
            }
        }).then(jxbResp=>{
            SellingServerUtil.getAccessibleServers(false, false)
            return Promise.all([SessionSellingServerUtil.renewCache(), SessionUserUtil.renewCache()]).then(() => {
                return jxbResp;
            })
        })
    }

    /**
     * 切换门店
     * 
     * @param {number|string} storeId 
     * @param {number} salesTeamId 
     * @returns {Promise<JxbResponse>}
     */
    static switchUnionStore(storeId, salesTeamId = 0){
        if(salesTeamId > 0){
            storeId = `${storeId}_${salesTeamId}`
        }
        return JxbHttpClient.getClient().post({
            url: 'AppMaster/AgentUnion/selectAgent',
            data: { agent_id: storeId }
        }).then(jxbResp=>{
            SellingServerUtil.getAccessibleServers(false, false)
            return Promise.all([SessionSellingServerUtil.renewCache(), SessionUserUtil.renewCache()]).then(() => {
                return jxbResp;
            })
        })
    }
}